#include "MotionListWidget.h"

#include <set>
#include <MMM/Exceptions.h>
#include <QListWidget>

MotionListWidget::MotionListWidget(const std::vector<std::string> &motionNames, const std::string &motionToolTipFirstPart) :
    QListWidget(),
    motionToolTipFirstPart(motionToolTipFirstPart)
{
    addMotionNames(motionNames);
    enableDragDrop();
}

void MotionListWidget::addMotionNames(const std::vector<std::string> &motionNames) {
    for (unsigned int index = 0; index < motionNames.size(); index++) {
        QListWidgetItem* item = new QListWidgetItem();
        item->setData(Qt::ToolTipRole, QString::fromStdString(motionToolTipFirstPart + motionNames.at(index)));
        item->setData(Qt::EditRole, QString::fromStdString(motionNames.at(index)));
        item->setData(Qt::CheckStateRole, Qt::Checked);
        item->setData(Qt::UserRole, QVariant(index));
        item->setFlags(item->flags() | Qt::ItemIsEditable);
        addItem(item);
    }
}

void MotionListWidget::enableDragDrop() {
    setSelectionMode(QAbstractItemView::SingleSelection);
    setDragEnabled(true);
    viewport()->setAcceptDrops(true);
    setDropIndicatorShown(true);
    setDragDropMode(QAbstractItemView::InternalMove);
}

std::vector<MMM::MotionListConfigurationPtr> MotionListWidget::getConfigurations() {
    std::vector<MMM::MotionListConfigurationPtr> configurations;
    std::set<std::string> motionNames;
    for (int index = 0; index < count(); index++) {
        MMM::MotionListConfigurationPtr configuration = getConfiguration(index);
        if (!configuration->isIgnoreMotion()) {
            std::string motionName = configuration->getMotionName();
            if (motionName.empty())
            {
                motionName = "Motion_" + std::to_string(index);
            }
            if (motionNames.find(motionName) != motionNames.end()) throw MMM::Exception::MMMException("Motion name '" + motionName + "' at index " + std::to_string(index) + " is already contained!");
            motionNames.insert(motionName);
        }
        configurations.push_back(configuration);
    }
    return configurations;
}

MMM::MotionListConfigurationPtr MotionListWidget::getConfiguration(int index) {
    QListWidgetItem* item = this->item(index);
    std::string name = item->data(Qt::EditRole).toString().toStdString();
    int oldIndex = item->data(Qt::UserRole).toInt();

    if (item->checkState() == Qt::Checked)
        return MMM::MotionListConfigurationPtr(new MMM::MotionListConfiguration(oldIndex, index, name));
    else return MMM::MotionListConfigurationPtr(new MMM::MotionListConfiguration(oldIndex, index, name, true));
}
